#!/usr/bin/env node

const _ = require('lodash');
const psList = require('ps-list');
const pidPort = require('pid-port');
const kill = require('tree-kill');
const utils = require('./js/utils');
const dialog = require('./js/dialog');

async function pidToPorts(pids) {
    const obj = {}
    for (const [port, pid_] of await pidPort.all()) {
        if (pids.indexOf(pid_) !== -1) {
            obj[pid_] = [...(obj[pid_]||[]), port];
        }
    }
    return obj;
}
async function getTaskList ({ name, pid }) {
    let list = await psList();
    if (name) {
        list = _.filter(list, o=>utils._r(name).test(o.name));
        const ports = await pidToPorts(_.map(list, 'pid'));
        _.forEach(list, o=>{
            const port = ports[o.pid];
            o.port = port ? port.join(',') : '';
        });
    } else {
        list = _.filter(list, o=>o.pid == pid);
    }
    return list.filter(o=>o.pid !== process.pid);
}
function allCallback(list) {
	console.log(`如果因为权限问题没有杀死子进程，可以粘贴到cmd自行运行，下面的code已经放入到clibboard`);
    const code = `taskkill ${list.map(o=>`/PID ${o.pid}`).join(' ')} /T /F`;
    console.log(code);
    utils.copy(code);
}
function singleCallback(obj) {
	console.log(`杀死了${obj.name}[${obj.pid}]${obj.port?`[:${obj.port}]`: ''}进程和其所有子进程`);
    kill(obj.pid);
}
async function showForName (name) {
    let list = await getTaskList({ name });
    list = list.map(o=>(o.show = m=>`[${m.pid}] ${m.name} ${m.port?`port:${m.port}`: ''}`, o));
    await dialog.checkbox("进程列表","选择进程杀掉", list, allCallback, singleCallback, true);
    process.exit();
}
async function showForPort (port) {
   const pid = await pidPort.portToPid(port);
    let list = await getTaskList({ pid });
    _.forEach(list, o=>{
        o.port = port;
    });
    list = list.map(o=>(o.show = m=>`[${m.pid}] ${m.name} ${m.port?`port:${m.port}`: ''}`, o));
    await dialog.checkbox("进程列表","选择进程杀掉", list, null, singleCallback, true);
    process.exit();
}

const param1 = process.argv[2];
if (!param1 || param1 === '-h' || param1 === '--help') {
    console.log('Usage: ');
    console.log();
    console.log('     xps name|:port');
    console.log();
    process.exit();
}
if (/^:\d+/.test(param1)) {
    showForPort(+param1.substr(1));
} else {
    showForName(param1);
}